/**
 * @file        main.c
 *
 * @brief       Main program body
 *
 * @version     V1.0.0
 *
 * @date        2024-12-01
 *
 * @attention
 *
 *  Copyright (C) 2024-2025 Geehy Semiconductor
 *
 *  You may not use this file except in compliance with the
 *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
 *
 *  The program is only for reference, which is distributed in the hope
 *  that it will be useful and instructional for customers to develop
 *  their software. Unless required by applicable law or agreed to in
 *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
 *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
 *  and limitations under the License.
 */

/* Includes ***************************************************************/
#include "main.h"

/* Private includes *******************************************************/

/* Private macro **********************************************************/

/* Private typedef ********************************************************/

/* Private variables ******************************************************/

/* Private function prototypes ********************************************/


/* External variables *****************************************************/

/* External functions *****************************************************/

void NVIC_Init()
{
		NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_1);
}

void GPIO_Init()
{
    GPIO_Config_T GPIO_ConfigStruct = {0U};

    /* Enable the GPIO Clock */
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);

    /* Configure the GPIO_LED pin */
    GPIO_ConfigStruct.pin = GPIO_PIN_4;
    GPIO_ConfigStruct.mode = GPIO_MODE_OUT_PP;
    GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;

    GPIO_Config(GPIOA, &GPIO_ConfigStruct);
    GPIO_SetBit(GPIOA,GPIO_PIN_4);
		    
    /* Enable the BUTTON Clock */
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_AFIO);
    
    /* Configure Button pin as input floating */
    GPIO_ConfigStruct.mode = GPIO_MODE_IN_PU;
    GPIO_ConfigStruct.pin = (GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 );
    GPIO_Config(GPIOA, &GPIO_ConfigStruct);
 
}

/**
 * @brief   SPI full duplex configuration
 *
 * @param   None
 *
 * @retval  None
 */
void SPI_Init(void)
{
    SPI_Config_T spiConfig;
    GPIO_Config_T gpioConfig;

    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SPI1);

    /* SPI1 gpio configuration */
    gpioConfig.pin = (GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
    gpioConfig.speed = GPIO_SPEED_50MHz;
    gpioConfig.mode = GPIO_MODE_AF_PP;
    GPIO_Config(GPIOA, &gpioConfig);

    /* SPI1 Configuration */
    spiConfig.mode = SPI_MODE_MASTER;
    spiConfig.length = SPI_DATA_LENGTH_8B;
    spiConfig.phase = SPI_CLKPHA_2EDGE;
    spiConfig.polarity = SPI_CLKPOL_HIGH;
    spiConfig.nss = SPI_NSS_SOFT;
    spiConfig.firstBit = SPI_FIRSTBIT_MSB;
    spiConfig.direction = SPI_DIRECTION_2LINES_FULLDUPLEX;
    spiConfig.baudrateDiv = SPI_BAUDRATE_DIV_4;
    SPI_Config(SPI1, &spiConfig);

    //SPI_Enable(SPI1);
}
void DMA_Init(void)
{
	  DMA_Config_T DMA_ConfigStruct;
	
    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA1);
	
		//MEM->SPI1_TX DMA1 Channel3
    DMA_Reset(DMA1_Channel3);

    DMA_ConfigStructInit(&DMA_ConfigStruct);
    DMA_ConfigStruct.peripheralBaseAddr = 0;
    DMA_ConfigStruct.memoryBaseAddr = 0;
    DMA_ConfigStruct.dir = DMA_DIR_PERIPHERAL_DST;
    DMA_ConfigStruct.bufferSize = 0;
    DMA_ConfigStruct.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
    DMA_ConfigStruct.memoryInc = DMA_MEMORY_INC_ENABLE;
    DMA_ConfigStruct.peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_BYTE;
    DMA_ConfigStruct.memoryDataSize = DMA_MEMORY_DATA_SIZE_BYTE;
    DMA_ConfigStruct.loopMode = DMA_MODE_NORMAL;
    DMA_ConfigStruct.priority = DMA_PRIORITY_HIGH;
    DMA_ConfigStruct.M2M = DMA_M2MEN_DISABLE;
	
    DMA_Config(DMA1_Channel3, &DMA_ConfigStruct);

    //DMA_Enable(DMA2_Channel3);

		//SPI1_RX->MEM DMA1 Channel2
    DMA_Reset(DMA1_Channel2);
		
    DMA_ConfigStructInit(&DMA_ConfigStruct);
    DMA_ConfigStruct.peripheralBaseAddr = (uint32_t)SPI1->DATA;
    DMA_ConfigStruct.memoryBaseAddr = 0;
    DMA_ConfigStruct.dir = DMA_DIR_PERIPHERAL_SRC;
    DMA_ConfigStruct.bufferSize = 0;
    DMA_ConfigStruct.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
    DMA_ConfigStruct.memoryInc = DMA_MEMORY_INC_ENABLE;
    DMA_ConfigStruct.peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_BYTE;
    DMA_ConfigStruct.memoryDataSize = DMA_MEMORY_DATA_SIZE_BYTE;
    DMA_ConfigStruct.loopMode = DMA_MODE_NORMAL;
    DMA_ConfigStruct.priority = DMA_PRIORITY_HIGH;
    DMA_ConfigStruct.M2M = DMA_M2MEN_DISABLE;
	
    DMA_Config(DMA1_Channel2, &DMA_ConfigStruct);

    //DMA_Enable(DMA2_Channel2);
}
void TMR_Init(void)
{
    TMR_BaseConfig_T tmrBaseConfig;

    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR2);

    /* TMR clock source frequency = 120MHz */
    tmrBaseConfig.countMode = TMR_COUNTER_MODE_UP;
    tmrBaseConfig.clockDivision = TMR_CLOCK_DIV_1;
    tmrBaseConfig.period = 999;
    tmrBaseConfig.division = 119;
    tmrBaseConfig.repetitionCounter = 0;
    TMR_ConfigTimeBase(TMR2, &tmrBaseConfig);

    TMR_EnableInterrupt(TMR2, TMR_INT_UPDATE);
    NVIC_EnableIRQRequest(TMR2_IRQn, 0x0, 0x6);

    //TMR_Enable(TMR2);
}
void EINT_Init()
{
    EINT_Config_T EINT_ConfigStruct = {0U};
        
		/* Connect Button EINT Line to Button GPIO Pin */
		GPIO_ConfigEINTLine(GPIO_PORT_SOURCE_A, GPIO_PIN_SOURCE_1);
		GPIO_ConfigEINTLine(GPIO_PORT_SOURCE_A, GPIO_PIN_SOURCE_2);
		GPIO_ConfigEINTLine(GPIO_PORT_SOURCE_A, GPIO_PIN_SOURCE_3);

		/* Configure Button EINT line */
		EINT_ConfigStruct.line = EINT_LINE_1;
		EINT_ConfigStruct.mode = EINT_MODE_INTERRUPT;
		EINT_ConfigStruct.trigger = EINT_TRIGGER_FALLING;
		EINT_ConfigStruct.lineCmd = ENABLE;
		EINT_Config(&EINT_ConfigStruct);
		
		EINT_ConfigStruct.line = EINT_LINE_2;
		EINT_Config(&EINT_ConfigStruct);
		
		EINT_ConfigStruct.line = EINT_LINE_3;
		EINT_Config(&EINT_ConfigStruct);

		/* Enable and set Button EINT Interrupt to the lowest priority */
		NVIC_EnableIRQRequest(EINT1_IRQn, 0x00, 0x05);
		NVIC_EnableIRQRequest(EINT2_IRQn, 0x00, 0x05);
		NVIC_EnableIRQRequest(EINT3_IRQn, 0x00, 0x05);
}

/**
 * @brief   Main program
 *
 * @param   None
 *
 * @retval  None
 */
int main(void)
{
		NVIC_Init();
		GPIO_Init();
		SPI_Init();
		DMA_Init();
		TMR_Init();
		EINT_Init();
    /* Infinite loop */
    while (1)
    {
			extern int Application_main(void);
			Application_main();
    }
}

